﻿/**
 * 过滤代码
 */
(function(E){
var Consts = E.consts, timeids = [], badTags={updated:[], deleted:[]}, Utils = E.mod('Utils');

//允许保留的标签、属性和样式
var allowTags,
	MainAllowTags = {
		'font':[],
		'span' : ['class','style', '.font-weight', '.font-style', '.text-decoration'],
		'div' : ['class','id','style','.width','.text-align'],
		'a' : ['class','href', 'target', 'title', 'alt', 'name'],
		'img' : ['class', 'id', 'src', 'alt', 'title', 'align', 'usemap', 'border', 'name', 'width', '/'],
		'hr' : ['/'],
		'br' : ['/'],
		'p' : ['class','align','style','.text-align'],
		'table' : [
			'class','style','width','.width','align',
			'border','bordercolor', 'cellpadding',
			'.margin', '.margin-left','.margin-right'
			],
		'tbody': [],
		'tr': [],
		'th': ['class','align','colspan','rowspan','width'],
		'td': ['class','align','colspan','rowspan','width'],
		'ol': ['class'],
		'ul': ['class'],
		'li': ['class'],
		'sub': ['class'],
		'sup': ['class','name'],
		'blockquote': ['style', '.margin', '.padding'],
		'h2': [],
		'h3': [],
		'h4': [],
		'h5': [],
		'h6': [],
		'em': [],
		'strong': ['style','.width'],
		'b': [],
		'i':[],
		'u': [],
		'strike': [],
		'object':['classid','class','id','width','height','codebase'],
		'embed' : ['style','src', 'type', 'loop', 'autostart', 'quality', '.width', '.height','flename','width','height','volume','pluginspage','console','controls','/'],
		'param':['name','value'],
		'map':['id', 'name'],
		'area':['shape', 'coords', 'href', 'title', '/']
	},
	nodeAttrs = ['onerror','onclick','onmouseout','onmouseover','onmousemove','align'
	,'color','font','height','vspace','hspace','id','class','style','left'
	,'right','name','rel','size','title','width','valign','bgcolor','dir'];
	
E.plugin("Cleanup", {
	click: function( callback ){
		var option = E.get('option'),
			dom = E.get('document');
		if( $.inArray('Cleanup', option.disabled) === -1 ){
			this.exec( dom.body, callback );
		}
	},
	
	exec: function( context, callback ){
		if( typeof context !== 'object' ){
			return ;
		}
		var Message = E.mod('Message'),
			option = E.get('option');
			
		if( option.allowTags && typeof option.allowTags === 'object' ){
			allowTags = $.extend( {}, MainAllowTags, option.allowTags );
		}else{
			allowTags = MainAllowTags;
		}
		
		Message.showNotice('正在进行源码清理，请稍等......', 20000);
		scanNodes( context );
		
		if( typeof callback === "function" ){
			callback();
		}
		
		clearTimeout( timeids[E.eid] );
		timeids[E.eid] = setTimeout(function(){
			Message.change('正在进行源码清理，请稍等......完成！');
			clearTimeout( timeids[E.eid] );
			timeids[E.eid] = setTimeout(function(){
				Message.hide();
			}, 500);
		}, 100);
		return true;
	}
});

	
/**
 * 扫描标签和标签属性，清除到不在保留列表的标签和属性
 * 
 */
function scanNodes ( el ){
	var attList=[], nodes = el.childNodes;
	for (var i = 0; i < nodes.length; i++){
		var node = nodes[i];
		if (1 == node.nodeType){
			// nodeType = 1 是元素节点
			var tagName = node.tagName.toLowerCase();
			
			if (allowTags[tagName]){
				// 2011-07-22 潘雪鹏
				// IE也支持node.attributes属性，但是node.attributes将返回标签支持的所有属性，
				// 多达100多个，而非iE浏览器仅返回标签里面出现的属性，
				// 所以ie下的node.attributes在此处会导致严重的性能问题，
				// 解决办法就是，ie下给一个指定好的属性黑名单。
				var attrList = (Consts.IE)? nodeAttrs : Utils.clone(node.attributes);
				var attrs = allowTags[tagName], styles = '';
				
				var attrName;
				// 先过滤属性
				for (var j = 0, len = attrList.length; j < len; j++){
					attrName = (Consts.IE) ? attrList[j] : attrList[j].name.toLowerCase();
					if ($.inArray(attrName, attrs) == -1){
						node.removeAttribute(attrName);
						E.log('run', '清理标签'+node.tagName+'的属性'+attrName);
						attList[attrName] = node.getAttribute(attrName);
					}
				}
				
				styles = Consts.IE ? node.style.cssText : node.getAttribute('style');
				
				// 后过滤样式
				if( styles ){
					styles = styles.replace(/; /g, ';').toLowerCase();
					var _style, styleList = styles.split(';');
					for (var j=0, len = styleList.length; j<len; j++){
						_style = styleList[j].split(':');
						if (_style.length == 2 && $.inArray('.'+_style[0], attrs) == -1){
							styles = styles.replace(new RegExp(_style[0]+":"+_style[1]+";?", 'i'), '');
						}
					}
					styles = $.trim(styles);
					if( styles ){
						Consts.IE ?	(node.style.cssText = styles)
							: node.setAttribute('style', styles);
					}else{
						node.removeAttribute('style')
					}
				}
				
				// 针对表格节点，进行特殊处理
				if( (tagName === 'table') ){
					var table = $(node), bordercolor = table.attr('bordercolor');
					if( !table.hasClass('jqe-table') ){
						table.addClass('jqe-table');
					}
					if( !bordercolor ){
						table.attr('bordercolor', '#cccccc');
					}
					
					table.attr('border', 1);
				}
				
				if (node.hasChildNodes()) {
					scanNodes(node);
				}
			}else if (node.hasChildNodes()){
				//对于有子元素的不合法标签进行深入遍历，保证删除标签而保留其内容。
				for(var j=0; j<node.childNodes.length; j++){
					scanNodes(node.childNodes[j]);
					node.parentNode.insertBefore(node.childNodes[j].cloneNode(true), node);
				}
				node.parentNode.removeChild(node);
			}else{
				//没有子元素的不合法标签，直接删除
				node.parentNode.removeChild(node);
			}
		}
	}
	
	return el.innerHTML;
}

/*
* 将所有的 FONT 标签转为 span 标签，但最多转换1000个
* 尚未实现将 b u i 标签转为样式
*/
/*
function font2style( ){
	var self=this, num=0;
	var fontSize={
		  "1" : "8",
		  "2" : "10",
		  "3" : "12",
		  "4" : "14",
		  "5" : "18",
		  "6" : "24",
		  "7" : "36"
	}
	//font to style
	
	function change(el){
		var font=$(el), html=font.html(), style=font.attr('style'),
			size=font.attr('size'), color=font.attr('color');
		
		if(style || size || color){
			style = style || '';
			if(size){
				style+= 'font-size:'+fontSize[size]+'px;';
			}
			
			if(color){
				style+= 'color:'+color+';';
			}
			
			html='<span style="'+style+'">'+html+'</span>';
		}
		font.before(html).remove();
	}
	
	//为防止死循环，最多转换5000个
	while($('font', dom).length && num++ < 5000){
		$('font', dom).each(function(){
			change(this);
		});
	}
}
*/

/*
* 将所有的 span 标签转为 font u b i 标签，
* 最多转换1000个，没有任何样式的span标签将被删除
*/
/*
function style2font( ){
	var self=this, num=0;
	//style to font
	var fontSize={
		  "8px"   : "1",
		  "10px"   : "2",
		  "12px"   : "3",
		  "14px"   : "4",
		  "18px"   : "5",
		  "24px"   : "6",
		  "36px"   : "7"
	}
	
	function change(el){
		var span=$(el), html='', style=span.attr('style');
		
		var color=span.css('color'), bgColor=span.css('backgroundColor'), size=span.css('fontSize'),
			B=span.css('fontWeight'), U=span.css('textDecoration'), I=span.css('fontStyle');
		
		if(!/[^\w]?color\:/i.test(style)) color='';
		if(!/background\-color/i.test(style)) bgColor='';
		if(!/font\-size/i.test(style)) size='';
		
		if(!/font\-weight/i.test(style)) B='';
		if(!/underline/i.test(style)) U='';
		if(!/font\-style/i.test(style)) I='';
		
		if(color || bgColor || size){
			html='<font';
			
			if($.IE){
				if(bgColor){
					html += ' style="background-color:'+bgColor+'"';
				}
				
				if(color){
					html += ' color="'+color+'"';
				}
			}else{
				if(bgColor && color){
					html += ' style="background-color:'+bgColor+';color:'+color+'"';
				}else if(bgColor){
					html += ' style="background-color:'+bgColor+'"';
				}else if(color){
					html += ' style="color:'+color+'"';
				}
			}
				
			if(size){
				html += ' size="'+fontSize[size]+'"';
			}
			
			html += '>'+span.html()+'</font>';
			if(B) html = '<b>'+html+'</b>';
			if(I) html = '<i>'+html+'</i>';
			if(U) html = '<u>'+html+'</u>';
			
			span.before(html).remove();
		}else{
			html = span.html();
			if(B) html = '<b>'+html+'</b>';
			if(I) html = '<i>'+html+'</i>';
			if(U) html = '<u>'+html+'</u>';
			span.before(html).remove();
		}
		
		
	}
	
	//为防止死循环，最多转换5000个，将没有任何样式的span标签删除
	while($('span', dom).length && num++ < 5000){
		$('span', dom).each(function(){
			change(this);
		});
	}
}
*/

})(jQEditor);